<template>
	<tm-sheet :eventPenetrationEnabled="true" :transprent="true" :margin="props.margin" :padding="props.padding">
		<tm-sheet
			:transprent="props.transprent"
			:round="props.round"
			no-level
			:margin="[0, 0]"
			:padding="_inputPadding"
			:border="props.border"
			:text="props.text"
			:color="_color"
			:outlined="props.outlined"
			:shadow="props.shadow"
			:linear="props.linear"
			:linearDeep="props.linearDeep"
			_style="transition:border 0.24s"
		>
			<view
				class="flex flex-row relative"
				@click="inputClick($event, '')"
				:class="[propsDetail.type == 'textarea' ? propsDetail.layoutAlign : 'flex-row-center-start']"
				:style="[propsDetail.autoHeight && propsDetail.type == 'textarea' ? {} : { height: `${_height}rpx` }]"
			>
				<view v-if="propsDetail.search || propsDetail.searchLabel" class="px-9"></view>
				<slot name="left"></slot>
				<view v-if="propsDetail.prefix" class="pr-16">
					<tm-icon
						_style="transition:color 0.24s"
						:font-size="propsDetail.fontSize"
						:color="props.prefixColor"
						:name="propsDetail.prefix"
						:customicon="props.customicon"
					></tm-icon>
				</view>
				<view v-if="propsDetail.prefixLabel" class="pr-24">
					<tm-text
						_style="transition:color 0.24s"
						:font-size="propsDetail.fontSize"
						:color="props.prefixColor"
						:label="propsDetail.prefixLabel"
					></tm-text>
				</view>

				<view v-if="!isAndroid" @click="inputClick($event, 'ali')" class="flex-1 relative flex-row flex" :style="[{ width: '0px' }]">
					<!-- <view @click.stop="emits('click',$event)" class=" l-0 t-0 flex-1 " :style="{height: `${_height}rpx`,background:'red'}"></view> -->
					<input
						class="flex-1"
						:userInteractionEnabled="false"
						v-if="propsDetail.type != 'textarea'"
						:value="_value"
						:focus="propsDetail.focus"
						@focus="focus"
						@blur="blur"
						@confirm="confirm"
						@input="inputHandler"
						@keyboardheightchange="emits('keyboardheightchange', $event)"
						:password="showPasswordText"
						:maxlength="propsDetail.maxlength"
						:disabled="propsDetail.disabled"
						:cursorSpacing="propsDetail.cursorSpacing"
						:confirmType="propsDetail.confirmType"
						:confirmHold="propsDetail.confirmHold"
						:autoBlur="propsDetail.autoBlur"
						:holdKeyboard="propsDetail.holdKeyboard"
						:adjustPosition="propsDetail.adjustPosition"
						:readonly="propsDetail.readyOnly"
						:type="propsDetail.type"
						:placeholder="propsDetail.placeholder"
						:style="[
							{
								height: `${_height}rpx`,
								color: propsDetail.fontColor ? propsDetail.fontColor : tmcomputed.textColor,
								'text-align': props.align,
								fontSize: `${propsDetail.fontSize_px}px`,
								transition: 'color 0.24s'
							}
						]"
						:placeholder-style="`fontSize:${propsDetail.fontSize_px}px;${props.placeholderStyle}`"
						:ready-only="propsDetail.readyOnly"
					/>

					<textarea
						:userInteractionEnabled="false"
						v-if="propsDetail.type == 'textarea'"
						:value="_value"
						:focus="propsDetail.focus"
						@focus="focus"
						@blur="blur"
						@confirm="confirm"
						@input="inputHandler"
						@keyboardheightchange="emits('keyboardheightchange', $event)"
						:maxlength="propsDetail.maxlength"
						:disabled="propsDetail.disabled"
						:placeholder="propsDetail.placeholder"
						:cursorSpacing="propsDetail.cursorSpacing"
						:confirmHold="propsDetail.confirmHold"
						:autoBlur="propsDetail.autoBlur"
						:holdKeyboard="propsDetail.holdKeyboard"
						:cursor="propsDetail.cursor"
						:show-confirm-bar="propsDetail.showConfirmBar"
						:selectionStart="propsDetail.selectionStart"
						:selectionEnd="propsDetail.selectionEnd"
						:disable-default-padding="propsDetail.disableDefaultPadding"
						:fixed="propsDetail.fixed"
						:autoHeight="propsDetail.autoHeight"
						:readonly="propsDetail.readyOnly"
						:adjustPosition="propsDetail.adjustPosition"
						:type="propsDetail.type"
						:style="[
							propsDetail.autoHeight ? {} : { height: `${_height}rpx` },
							{
								width: 'auto',
								'word-break': 'break-word',
								color: propsDetail.fontColor ? propsDetail.fontColor : tmcomputed.textColor,
								'text-align': props.align,
								fontSize: `${propsDetail.fontSize_px}px`,
								transition: 'color 0.24s'
							}
						]"
						class="wrap flex-1"
						:placeholder-style="`fontSize:${propsDetail.fontSize_px}px;${props.placeholderStyle}`"
						:ready-only="propsDetail.readyOnly"
					></textarea>
				</view>
				<view v-if="isAndroid" class="flex-1 relative flex-row flex" :style="[{ width: '0px' }]">
					<!-- <view @click.stop="emits('click',$event)" class=" l-0 t-0 flex-1 " :style="{height: `${_height}rpx`,background:'red'}"></view> -->
					<input
						class="flex-1"
						@click.stop="emits('click', $event)"
						:userInteractionEnabled="false"
						v-if="propsDetail.type != 'textarea'"
						:value="_value"
						:focus="propsDetail.focus"
						@focus="focus"
						@blur="blur"
						@confirm="confirm"
						@input="inputHandler"
						@keyboardheightchange="emits('keyboardheightchange', $event)"
						:password="showPasswordText"
						:disabled="propsDetail.disabled"
						:cursorSpacing="propsDetail.cursorSpacing"
						:confirmType="propsDetail.confirmType"
						:confirmHold="propsDetail.confirmHold"
						:autoBlur="propsDetail.autoBlur"
						:holdKeyboard="propsDetail.holdKeyboard"
						:adjustPosition="propsDetail.adjustPosition"
						:maxlength="propsDetail.maxlength"
						:type="propsDetail.type"
						:readonly="propsDetail.readyOnly"
						:placeholder="propsDetail.placeholder"
						:style="[
							{
								height: `${_height}rpx`,
								color: propsDetail.fontColor ? propsDetail.fontColor : tmcomputed.textColor,
								'text-align': props.align,
								fontSize: `${propsDetail.fontSize_px}px`
							}
						]"
						:placeholder-style="`fontSize:${propsDetail.fontSize_px}px;${props.placeholderStyle}`"
					/>
					<textarea
						@click.stop="emits('click', $event)"
						:userInteractionEnabled="false"
						v-if="propsDetail.type == 'textarea'"
						:value="_value"
						:focus="propsDetail.focus"
						@focus="focus"
						@blur="blur"
						@confirm="confirm"
						@input="inputHandler"
						@keyboardheightchange="emits('keyboardheightchange', $event)"
						:disabled="propsDetail.disabled"
						:placeholder="propsDetail.placeholder"
						:cursorSpacing="propsDetail.cursorSpacing"
						:confirmHold="propsDetail.confirmHold"
						:autoBlur="propsDetail.autoBlur"
						:holdKeyboard="propsDetail.holdKeyboard"
						:adjustPosition="propsDetail.adjustPosition"
						:maxlength="propsDetail.maxlength"
						:autoHeight="propsDetail.autoHeight"
						:cursor="propsDetail.cursor"
						:show-confirm-bar="propsDetail.showConfirmBar"
						:selectionStart="propsDetail.selectionStart"
						:selectionEnd="propsDetail.selectionEnd"
						:disable-default-padding="propsDetail.disableDefaultPadding"
						:readonly="propsDetail.readyOnly"
						:fixed="propsDetail.fixed"
						:type="propsDetail.type"
						:style="[
							propsDetail.autoHeight ? {} : { height: `${_height}rpx` },
							{
								width: 'auto',
								'word-break': 'break-word',
								color: propsDetail.fontColor ? propsDetail.fontColor : tmcomputed.textColor,
								'text-align': props.align,
								fontSize: `${propsDetail.fontSize_px}px`
							}
						]"
						class="wrap flex-1"
						:placeholder-style="`fontSize:${propsDetail.fontSize_px}px;${props.placeholderStyle}`"
					></textarea>
				</view>
				<view @click="clearBtn" class="pl-16" v-if="propsDetail.showClear && _valueLenChar > 0">
					<tm-icon
						:customicon="props.customicon"
						_style="transition:color 0.24s"
						:userInteractionEnabled="false"
						:font-size="propsDetail.fontSize"
						:color="props.clearAndEyeColor"
						name="tmicon-times-circle-fill"
					>
					</tm-icon>
				</view>
				<view class="pl-16" v-if="_requiredError">
					<tm-icon _style="transition:color 0.24s" :font-size="propsDetail.fontSize" name="tmicon-exclamation-circle"></tm-icon>
				</view>
				<view class="pl-16" v-if="propsDetail.suffix">
					<tm-icon
						:customicon="props.customicon"
						_style="transition:color 0.24s"
						:font-size="propsDetail.fontSize"
						:color="props.suffixColor"
						:name="propsDetail.suffix"
					></tm-icon>
				</view>

				<view v-if="propsDetail.suffixLabel" class="pl-16">
					<tm-text
						_style="transition:color 0.24s"
						:font-size="propsDetail.fontSize"
						:color="props.suffixColor"
						:label="propsDetail.suffixLabel"
					></tm-text>
				</view>

				<view @click="changeSeePassword" class="pl-16" v-if="showPasswordIcon">
					<!-- tmicon-eyeslash-fill -->
					<tm-icon
						:color="props.clearAndEyeColor"
						_style="transition:color 0.24s"
						:userInteractionEnabled="false"
						:font-size="propsDetail.fontSize"
						:name="showPasswordText ? 'tmicon-eyeslash-fill' : 'tmicon-eye-fill'"
					></tm-icon>
				</view>

				<!-- #ifndef MP-ALIPAY -->
				<view v-if="propsDetail.showCharNumber && _valueLenChar > 0 && propsDetail.type != 'textarea'" class="pl-16 flex-row flex">
					<tm-text _style="transition:color 0.24s" :label="_valueLenChar"></tm-text>
					<tm-text _style="transition:color 0.24s" v-if="propsDetail.maxlength > 0" :label="'/' + propsDetail.maxlength"></tm-text>
				</view>
				<!-- 原因是支付宝小程序自带了计数器。会导致重叠。 -->
				<view
					v-if="propsDetail.showCharNumber && _valueLenChar > 0 && propsDetail.type == 'textarea'"
					class="pl-16 flex-row flex absolute r-0"
					:class="[`b-${12}`]"
				>
					<tm-text _style="transition:color 0.24s" :label="_valueLenChar"></tm-text>
					<tm-text _style="transition:color 0.24s" v-if="propsDetail.maxlength > 0" :label="'/' + propsDetail.maxlength"></tm-text>
				</view>
				<!-- #endif -->
				<slot name="right">
					<view v-if="propsDetail.search || propsDetail.searchLabel" class="pl-16">
						<TmButton
							:round="props.round"
							:width="props.searchWidth"
							:followTheme="props.followTheme"
							@click="searchClick"
							:color="props.searchBgColor"
							:font-size="24"
							:height="_height - 11"
							:padding="[16, 0]"
							:block="!props.searchWidth"
							:margin="[0, 0]"
							:fontColor="props.searchFontColor"
							:icon="propsDetail.search"
							:label="propsDetail.searchLabel"
						></TmButton>
					</view>
				</slot>
			</view>
		</tm-sheet>
	</tm-sheet>
</template>

<script lang="ts" setup>
import { computed, PropType, ref, watch, getCurrentInstance, inject, toRaw } from 'vue'
import { inputPushItem, rulesItem } from './../tm-form-item/interface'
import tmSheet from '../tm-sheet/tm-sheet.vue'
import tmIcon from '../tm-icon/tm-icon.vue'
import tmText from '../tm-text/tm-text.vue'
import { custom_props, computedTheme, computedClass, computedStyle, computedDark } from '../../tool/lib/minxs'
import { useTmpiniaStore } from '../../tool/lib/tmpinia'
import TmButton from '../tm-button/tm-button.vue'
const store = useTmpiniaStore()
const emits = defineEmits(['focus', 'blur', 'confirm', 'input', 'update:modelValue', 'clear', 'search', 'keyboardheightchange', 'click'])
const proxy = getCurrentInstance()?.proxy ?? null
const props = defineProps({
	...custom_props,
	followTheme: {
		type: [Boolean, String],
		default: true
	},
	color: {
		type: String,
		default: 'grey-4'
	},
	searchBgColor:{
		type: String,
		default: 'primary'
	},
	searchFontColor: {
		type: String,
		default: ''
	},
	searchWidth: {
		type: Number,
		default: 0
	},
	prefixColor: {
		type: String,
		default: ''
	},
	suffixColor: {
		type: String,
		default: ''
	},
	//激活时的主题配色。
	focusColor: {
		type: String,
		default: 'primary'
	},
	/** 清除按钮，显示密码按钮的颜色 */
	clearAndEyeColor:{
		type: String,
		default: ''
	},
	//默认使用自动配色
	fontColor: {
		type: String,
		default: ''
	},
	text: {
		type: Boolean,
		default: true
	},
	outlined: {
		type: Boolean,
		default: false
	},
	border: {
		type: Number,
		default: 0
	},
	transprent: {
		type: Boolean,
		default: false
	},
	round: {
		type: Number,
		default: 3
	},
	shadow: {
		type: Number,
		default: 0
	},
	margin: {
		type: Array as PropType<Array<number>>,
		default: () => [0, 0]
	},
	padding: {
		type: Array as PropType<Array<number>>,
		default: () => [0, 0]
	},
	height: {
		type: Number,
		default: 64
	},
	//前缀图标
	prefix: {
		type: String,
		default: ''
	},
	//前缀文字
	prefixLabel: {
		type: String,
		default: ''
	},
	//后缀图标
	suffix: {
		type: String,
		default: ''
	},
	//后缀文字
	suffixLabel: {
		type: String,
		default: ''
	},

	fontSize: {
		type: Number,
		default: 30
	},
	//tmicon-search
	search: {
		type: String,
		default: ''
	},
	//搜索
	searchLabel: {
		type: String,
		default: ''
	},
	showClear: {
		type: Boolean,
		default: false
	},
	password: {
		type: Boolean,
		default: false
	},
	//是否禁用
	disabled: {
		type: Boolean,
		default: false
	},
	placeholder: {
		type: String,
		default: '请输入内容'
	},
	//错误时，提示的文本。
	errorLabel: {
		type: String,
		default: '请输入内容'
	},
	//对齐方式。
	//left,right,center
	align: {
		type: String as PropType<'left' | 'right' | 'center'>,
		default: 'left'
	},
	modelValue: {
		type: [String, Number],
		default: ''
	},
	inputPadding: {
		type: Array as PropType<Array<number>>,
		default: () => [24, 0]
	},
	//是否显示字符统计。
	showCharNumber: {
		type: Boolean,
		default: false
	},
	maxlength: {
		type: Number,
		default: -1
	},
	type: {
		type: String as PropType<'text' | 'number' | 'idcard' | 'digit' | 'tel' | 'safe-password' | 'nickname' | 'textarea'>,
		default: 'text'
	},
	cursorSpacing: {
		type: Number,
		default: 24
	},
	confirmType: {
		type: String as PropType<'send' | 'search' | 'next' | 'go' | 'done'>,
		default: 'done'
	},
	confirmHold: {
		type: Boolean,
		default: false
	},
	autoBlur: {
		type: Boolean,
		default: true
	},
	holdKeyboard: {
		type: Boolean,
		default: false
	},
	adjustPosition: {
		type: Boolean,
		default: true
	},
	//默认的聚集状态
	focus: {
		type: Boolean,
		default: false
	},
	cursor: {
		type: Number,
		default: 0
	},
	showConfirmBar: {
		type: Boolean,
		default: true
	},
	selectionStart: {
		type: Number,
		default: -1
	},
	selectionEnd: {
		type: Number,
		default: -1
	},
	disableDefaultPadding: {
		type: Boolean,
		default: false
	},
	fixed: {
		type: Boolean,
		default: false
	},
	placeholderStyle: {
		type: String,
		default: ''
	},
	autoHeight: {
		type: Boolean,
		default: false
	},
	readyOnly: {
		type: Boolean,
		default: false
	},
	/**横向布局的对齐类,主要是用来配置文本域时,左图标需要顶对齐或者左中对齐. */
	layoutAlign: {
		type: String,
		default: 'flex-row-top-start'
	},
	customicon: {
		type: Boolean,
		default: false
	},
})

let parentFormItem: any = proxy?.$parent
while (parentFormItem) {
	if (parentFormItem?.tmFormComnameFormItem == 'tmFormComnameFormItem' || !parentFormItem) {
		break
	} else {
		parentFormItem = parentFormItem?.$parent ?? undefined
	}
}

const isAndroid = ref(false)
isAndroid.value = uni.getSystemInfoSync().osName == 'android' ? true : false
const _height = computed(() => props.height)
const _inputPadding = computed(() => {
	if (props.search !== '' || props.searchLabel !== '') {
		return [4, 0]
	}
	return props.inputPadding
})
let timerId: any = NaN
function debounce(func: Function, wait = 500, immediate = false) {
	// 清除定时器
	if (!isNaN(timerId)) clearTimeout(timerId)
	// 立即执行，此类情况一般用不到
	if (immediate) {
		var callNow = !timerId
		timerId = setTimeout(() => {
			timerId = NaN
		}, wait)

		if (callNow) typeof func === 'function' && func()
	} else {
		// 设置定时器，当最后一次操作后，timeout不会再被清除，所以在延时wait毫秒后执行func回调方法
		timerId = setTimeout(() => {
			typeof func === 'function' && func()
			timerId = NaN
		}, wait)
	}
}
const propsDetail = computed(() => {
	return {
		...props,
		fontSize_px: uni.upx2px(props.fontSize)
	}
})
const _blackValue = props.modelValue
// 设置响应式全局组件库配置表。
const tmcfg = computed(() => store.tmStore)
//自定义样式：
const customCSSStyle = computed(() => computedStyle(props))
//自定类
const customClass = computed(() => computedClass(props))
//是否暗黑模式。
const isDark = computed(() => computedDark(props, tmcfg.value))
//当前是否显示检验错误状态？
const _requiredError = ref(false)
//是否聚焦中。
const _foucsActive = ref(props.focus || false)
watch(
	() => props.focus,
	() => {
		_foucsActive.value = props.focus
	}
)
const _color = computed(() => {
	let color = props.color
	if (_foucsActive.value) {
		if (props.followTheme && store.tmStore.color) {
			color = store.tmStore.color
		} else {
			color = props.focusColor
		}
	}
	if (_requiredError.value) color = 'red'
	return color
})
//计算主题
const tmcomputed = computed(() => {
	const _props = { ...props, color: _color.value }
	return computedTheme(_props, isDark.value, tmcfg.value)
})

//显示密码和关闭密码。
const showPasswordText = ref(propsDetail.value.password)
const showPasswordIcon = computed(() => props.password)
const _errorLabel = ref(props.errorLabel)
const _value = ref(props.modelValue)
const _valueLenChar = computed(() => {
	//在ios上字符的长度不能采用str.length来计算。因为一个中文=2。一个英文=1；
	let str = String(_value.value).split('')
	return str.length
})
watch(
	() => props.modelValue,
	() => (_value.value = props.modelValue)
)

function searchClick() {
	emits('search', _value.value)
}
function clearBtn() {
	_value.value = ''
	emits('update:modelValue', '')
	emits('clear')
}
function changeSeePassword() {
	showPasswordText.value = !showPasswordText.value
}
function focus(e: any) {
	_foucsActive.value = true
	emits('focus', e)
	// pushFormItem();
}
function blur(e: any) {
	_foucsActive.value = false
	// pushFormItem();
	emits('blur', e)
}
function confirm() {
	emits('confirm', _value.value)
}
function inputHandler(e: CustomEvent) {
	// #ifndef MP-WEIXIN
	_value.value = e.detail.value
	// #endif
	emits('input', e.detail.value)
	emits('update:modelValue', e.detail.value)

	return e.detail.value
}
function inputClick(e: Event, type: string) {
	// e.stopPropagation();

	if (type == 'ali') {
		debounce(
			() => {
				emits('click', e)
			},
			200,
			true
		)
		return
	} else {
		debounce(() => emits('click', e), 200, true)
	}
}
</script>

<style scoped>
/* #ifndef APP-NVUE */
input,
textarea {
	background-color: transparent;
	background: transparent;
}

/* #endif */
</style>
